﻿using System;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vowei.Web.Controllers;
using Vowei.Core.Models;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using Vowei.Data.Helpers;
using Vowei.Data;
using Vowei.Data.Models;
using NMock2;
using Autofac;
using Vowei.Web;
using Autofac.Integration.Web;
using Vowei.Web.Helpers;


namespace vowei.test
{      
    /// <summary>
    ///This is a test class for CommentControllerTest and is intended
    ///to contain all CommentControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class CommentControllerTest : TestBase
    {
        /// <summary>
        ///A test for Create
        ///</summary>
        [TestMethod()]
        public void CreateCommentTest()
        {
            using (var context = new VoweiContextImpl())
            {
                var task = context.Tasks.First();
                var target = new CommentController(VoweiContext, Setting.DefaultFormUser);
                Comment comment = new Comment()
                {
                    Text = "CreateCommentTest",
                    PostType = EntityHelpers.GetEntityTypeName(typeof(Task)),
                    PostId = task.ID
                };

                var result = target.Create(comment);
                Assert.IsInstanceOfType(result, typeof(JsonResult));

                var jResult = result as JsonResult;
                Assert.AreNotEqual(0, ((Comment)jResult.Data).ID);
                Assert.AreEqual(comment.PostId, ((Comment)jResult.Data).PostId);
            }
        }

        [TestMethod]
        public void CreateCommentForTaskTest()
        {
            var mocks = new Mockery();
            var user = mocks.NewMock<IUser>();

            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var task = new Task()
                {
                    Title = "CreateCommentForTaskTest_Task",
                    AssignedTo = Setting.DefaultUserName,
                    StartDate = DateTime.Now,
                    DueDate = DateTime.Now + TimeSpan.FromDays(30)
                };
                var expectedText = "无任务信息的回复！";
                var comment = CommentHelpers.MakeComment(task, expectedText);

                Assert.AreEqual(task.ID, comment.PostId);
                Assert.AreEqual("Task", comment.PostType);
                Assert.AreEqual(Setting.DefaultUserName, comment.User);
                Assert.AreEqual(expectedText, comment.Text);
            }
        }

        [TestMethod]
        public void CreateCommentForRequirementTest()
        {
            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var requirement = context.Requirements.First();
                var expectedText = "无任务信息的回复！";
                var comment = CommentHelpers.MakeComment(requirement, expectedText);

                Assert.AreEqual(requirement.ID, comment.PostId);
                Assert.AreEqual("Requirement", comment.PostType);
                Assert.AreEqual(Setting.DefaultUserName, comment.User);
                Assert.AreEqual(expectedText, comment.Text);
            }
        }

        [TestMethod]
        public void CreateCommentForCommentTest()
        {
            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var task = context.Tasks.First();
                var expectedText = "针对回复的回复";
                var comment = CommentHelpers.MakeComment(task, "无任务信息的回复！");
                context.SaveChanges();

                var actual = CommentHelpers.MakeComment(comment, expectedText);
                Assert.AreEqual(comment.ID, actual.PostId);
                Assert.AreEqual("Comment", actual.PostType);
                Assert.AreEqual(Setting.DefaultUserName, actual.User);
                Assert.AreEqual(expectedText, actual.Text);
            }
        }

        [TestMethod]
        public void SaveCommentNoTaskInfoTest()
        {
            var controller = new CommentController(VoweiContext, Setting.DefaultFormUser);
            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var task = context.Tasks.First();
                var expected = CommentHelpers.MakeComment(task, "无任务信息的回复！");

                var result = controller.Create(expected) as JsonResult;
                Assert.IsNotNull(result);
                Assert.IsInstanceOfType(result.Data, typeof(Comment));

                var actual = (Comment)result.Data;
                Assert.AreEqual(expected.Text, actual.Text);
                Assert.AreEqual(expected.PostId, actual.PostId);
                Assert.AreEqual(expected.User, actual.User);
                Assert.AreNotEqual(0, actual.ID);
            }
        }

        [TestMethod]
        public void SaveCommentHasTaskAndChangeSetInfoTest()
        {
            var controller = new CommentController(VoweiContext, Setting.DefaultFormUser);
            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var task = context.Tasks.First();
                var expected = CommentHelpers.MakeComment(task,
                    string.Format("Change set [1] is made for work item #{0}", task.ID));
                var expectedText = string.Format(
                    "Change set <a href=\"/ChangeSet/Details/1\">[1]</a> " +
                    "is made for work item #<a href=\"/Task/Details/{0}\">{0}</a>",
                    task.ID);

                var result = controller.Create(expected) as JsonResult;
                Assert.IsNotNull(result);
                Assert.IsInstanceOfType(result.Data, typeof(Comment));

                var actual = (Comment)result.Data;
                Assert.AreEqual(expected.Text, actual.Text);
                Assert.AreEqual(expected.PostId, actual.PostId);
                Assert.AreEqual(expected.User, actual.User);
                Assert.AreNotEqual(0, actual.ID);
            }
        }

        [TestMethod]
        public void SaveCommentHasTaskInfoTest()
        {
            var controller = new CommentController(VoweiContext, Setting.DefaultFormUser);
            // First会自己帮我们仍出异常信息
            using (var context = new VoweiContextImpl())
            {
                var task = context.Tasks.First();
                var expected = CommentHelpers.MakeComment(task,
                    string.Format("Close work item #{0}", task.ID));
                var expectedText = string.Format("Close work item <a href=\"/Task/Details/{0}\">{0}</a>", task.ID);

                var result = controller.Create(expected) as JsonResult;
                Assert.IsNotNull(result);
                Assert.IsInstanceOfType(result.Data, typeof(Comment));

                var actual = (Comment)result.Data;
                Assert.AreEqual(expected.Text, actual.Text);
                Assert.AreEqual(expected.PostId, actual.PostId);
                Assert.AreEqual(expected.User, actual.User);
                Assert.AreNotEqual(0, actual.ID);
            }
        }

        [TestMethod()]
        public void PostCommentsTest()
        {
            Comment[] comments = null;
            int prevMCount = 0, prevTCount = 0;
            var rid = Guid.Empty;
            var tid = Guid.Empty;

            var project = GetDefaultProject(VoweiContext);
            var requirement = new Requirement()
            {
                Title = "PostCommentsTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = (Project)project
            };
            var task = new Task()
            {
                Title = "PostCommentsTest_Task",
                AssignedTo = Setting.DefaultUserName,
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30),
                BelongsToMilestone = (Project)project
            };
            requirement.Children.Add(task);
            VoweiContext.Requirements.Add(requirement);
            VoweiContext.SaveChanges();

            comments = new Comment[]{
                    new Comment(){
                        PostId = task.ID,
                        PostType = "Task",
                        Text = "测试回复",
                        User = "yimin_shi@hotmail.com",
                        CommentDate = DateTime.Now
                    },
                    new Comment()
                    {
                        PostId = task.ID,
                        PostType = "Task",
                        Text = "测试回复2",
                        User = "yimin_shi@hotmail.com",
                        CommentDate = DateTime.Now
                    },
                    new Comment()
                    {
                        PostId = requirement.ID,
                        PostType = "Requirement",
                        Text = "测试回复3",
                        User = "yimin_shi@hotmail.com",
                        CommentDate = DateTime.Now
                    }
                };

            prevMCount = requirement.Comments.Count();
            prevTCount = task.Comments.Count();
            rid = requirement.ID;
            tid = task.ID;

            CommentController target = new CommentController(VoweiContext, Setting.DefaultFormUser);
            var expected = new HttpStatusCodeResult(200);
            var actual = (HttpStatusCodeResult)target.PostComments(comments);

            using (var context = new VoweiContextImpl())
            {
                task = context.Tasks.Include("Comments").First(t => t.ID == tid);
                requirement = context.Requirements.Include("Comments").First(r => r.ID == rid);
                Assert.AreEqual(expected.StatusCode, actual.StatusCode);

                Assert.AreEqual(prevMCount + 1, requirement.Comments.Count());
                Assert.AreEqual(prevTCount + 2, task.Comments.Count());
            }
        }

        [TestMethod]
        public void PostSvnCommentsBasicTest()
        {
            var pid = Guid.Empty;
            var tid = Guid.Empty;

            var project = new Project()
            {
                Title = "PostSvnCommentsBasicTest_Project",
                Owner = Setting.DefaultUserName,
                ScmType = Project.SupportedScm.Svn,
                ScmUrl = "https://hw-yishi-2/svn/VoweiTest/"
            };

            var requirement = new Requirement()
            {
                Title = "PostSvnCommentsBasicTest_Requirement",
                AssignedTo = Setting.DefaultUserName,
                BelongsToMilestone = project
            };
            var task = new Task()
            {
                Title = "PostSvnCommentsBasicTest_Task",
                AssignedTo = Setting.DefaultUserName,
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30),
                BelongsToMilestone = project
            };
            requirement.Children.Add(task);
            VoweiContext.Requirements.Add(requirement);
            VoweiContext.Projects.Add(project);
            VoweiContext.Tasks.Add(task);
            VoweiContext.SaveChanges();

            pid = project.ID;
            tid = task.ID;

            var commentText = string.Format("Change set [37] is made for work item {0}. \n" +
                                            "-------------------------------------------- \n" +
                                            "签入temp.txt来完成任务 #{0}\n\n" +
                                            "U 1.txt", tid.ToString("D"));
            var expectedText = string.Format("Change set <a href=/scm/details/?name=37&milestone={0}>[37]</a> is made for work item {1}. <BR />" +
                              "-------------------------------------------- <BR />" +
                              "签入temp.txt来完成任务 #{1}",
                              //"<a class=\"scm_file_changed\" href=\"https://hw-yishi-2/svn/VoweiTest/1.txt\">1.txt</a>",
                              pid.ToString("D"), tid.ToString("D"));

            var comments = new Comment[] {
                new Comment() {
                    PostId = tid,
                    Text = commentText,
                    User = Setting.DefaultUserName,
                    CommentDate = DateTime.Now
                }
            };
            var target = new CommentController(VoweiContext, Setting.DefaultFormUser);
            var expected = new HttpStatusCodeResult(200);
            var actual = (HttpStatusCodeResult)target.PostComments(comments);
            Assert.AreEqual(expected.StatusCode, actual.StatusCode);

            using (var context = new VoweiContextImpl())
            {
                var actualComment = context.Comments.Find(comments[0].ID);
                Assert.IsTrue(string.Compare(expectedText, actualComment.Text) == 0);
            }
        }
    }
}
